﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Domain.Core;
using System.Collections;
using Domain.Core.Extensions;
using System.Linq.Expressions;
using Domain.Core.Specification;

namespace Infrastructure.Core
{
    public class MockRepository<TEntity> :
        ICompleteRepository<TEntity> where TEntity : class
    {
        private readonly Dictionary<Type, IList> _entities = new Dictionary<Type, IList>();

        public Domain.Core.ICompleteRepository<TEntity> ICompleteRepository
        {
            get
            {
                throw new System.NotImplementedException();
            }
            set
            {
            }
        }
        #region Private Methods
        List<TEntity> GetTable<TEntity>()
        {
            if (!this._entities.ContainsKey(typeof(TEntity)))
            {
                this._entities[typeof(TEntity)] = new List<TEntity>();
            }
            return (List<TEntity>)this._entities[typeof(TEntity)];
        }
        void Insert(TEntity entity)
        {
            this.GetTable<TEntity>().Add(entity);
        }
        void Update(TEntity entity, TEntity original)
        {
            List<TEntity> entities = this.GetTable<TEntity>();
            int index = entities.IndexOf(original);
            if (index > -1)
            {
                entities[index] = entity;
            }
        }
        void Delete(TEntity entity)
        {
            this.GetTable<TEntity>().Remove(entity);
        }
        #endregion

        #region IExtensionRepository<T> 成员

        public void Add(IEnumerable<TEntity> item)
        {
            throw new NotImplementedException();
        }

        public void Modify(IEnumerable<TEntity> item)
        {
            throw new NotImplementedException();
        }

        public void Remove(IEnumerable<TEntity> item)
        {
            throw new NotImplementedException();
        }

        public TEntity Find(params object[] id)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IRepository<T> 成员

        public void Add(TEntity item)
        {
            this.Insert(item);
        }

        public void Remove(TEntity item)
        {
            this.Delete(item);
        }

        public void Modify(TEntity item)
        {
            throw new NotImplementedException();
        }

        public void Modify(Expression<Action<TEntity>> entity)
        {
            throw new NotImplementedException();
        }
        public TEntity GetEntity(ISpecification<TEntity> specification)
        {
            return GetEntities().FirstOrDefault(specification.SatisfiedBy());
        }
        public IQueryable<TEntity> GetEntities(Domain.Core.Specification.ISpecification<TEntity> specification)
        {
            return this.GetEntities().Where(specification.SatisfiedBy());
        }

        public IEnumerable<TEntity> GetEntities(Domain.Core.Specification.ISpecification<TEntity> specification, int pageIndex, int pageCount, Action<Domain.Core.Extensions.Orderable<TEntity>> order)
        {

            Orderable<TEntity> orderable;
            if (specification == null)
                orderable = new Orderable<TEntity>(GetEntities().AsQueryable());
            else
                orderable = new Orderable<TEntity>(GetEntities().Where(specification.SatisfiedBy()).AsQueryable());

            order(orderable);
            return orderable.Queryable
                            .Skip(pageIndex * pageCount)
                            .Take(pageCount);
        }

        public IEnumerable<TEntity> GetEntities(int pageIndex, int pageCount, Action<Domain.Core.Extensions.Orderable<TEntity>> order)
        {
            return GetEntities(null, pageIndex, pageCount, order);
        }

        public IQueryable<TEntity> GetEntities(System.Linq.Expressions.Expression<Func<TEntity, bool>> predicate)
        {
            return GetEntities().Where(predicate);
        }



        public IQueryable<TEntity> GetEntities()
        {
            return this.GetTable<TEntity>().AsQueryable();
        }

        #endregion

        #region IRepository<TEntity> 成员


        public TEntity GetEntity(Expression<Func<TEntity, bool>> predicate)
        {
            throw new NotImplementedException();
        }

        #endregion

         
    }
}
